/*
 * Copyright (C) 2012 mAPPn.Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.mol.market.common.util;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Observable;

import android.app.DownloadManager;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.os.Environment;
import android.os.Handler;

import com.mol.market.Constants;
import com.mol.market.R;
import com.mol.market.Session;
import com.mol.market.common.network.ApiAsyncTask.ApiRequestListener;
import com.mol.market.common.network.MarketAPI;
import com.mol.market.fanli.ui.TaskInformationActivity.RebateTask;

/**
 * 返利平台管理器
 *
 * @author andrew.wang
 * @date 2012-7-4
 */
public final class CashbackManager extends Observable implements
    ApiRequestListener {

  /**
   * 账户余额
   */
  private int mBalance;

  /**
   * 任务列表
   */
  private HashMap<String, CashbackTask> mTasks;

  /**
   * 下载任务表ID数组，用于查询状态
   */
  private long[] mTaskIdArray = new long[0];

  /**
   * 下载任务状态监听
   */
  private Cursor mCursor;

  /**
   * Application Contex
   */
  private Context mContext;

  private static CashbackManager mCashbackManager;

  public synchronized static CashbackManager get(Context context) {
        if (mCashbackManager == null) {
            mCashbackManager = new CashbackManager(context);
        }
        return mCashbackManager;
    }

  private CashbackManager(Context context) {
    mContext = context;
    init();
  }
  

  private Handler mHandler = new Handler();


  private ContentObserver mTaskObserver = new ContentObserver(mHandler) {

    @Override
    public void onChange(boolean selfChange) {
      super.onChange(selfChange);

      // 刷新下载任务状态
      refresh();
    }
  };
  

  /**
   * 初始化返利任务列表，获取下载状态查询指针,并回报同步失败的返利任务
   */
  private void init() {

    // 检查存储路径是否存在，以防止有些机型无法下载的问题
    File file = new File(Environment.getExternalStorageDirectory(), "gfan/rebate");
    if(!file.exists()) {
        file.mkdir();
    }
    
    // 获取任务列表
    mTasks = DBUtils.queryAllTask(mContext);

    if (mTasks == null || mTasks.size() == 0) {
      mTasks = new HashMap<String, CashbackManager.CashbackTask>();
      return;
    }

    // 获得状态查询指针
    int length = mTasks.size();
    Iterator<CashbackTask> values = mTasks.values().iterator();
    mTaskIdArray = new long[length];
    for (int i = 0; i < length; i++) {
      mTaskIdArray[i] = values.next().taskId;
    }
    mCursor = CashbackUtils.queryWithId(mContext, mTaskIdArray);
    mCursor.registerContentObserver(mTaskObserver);

    // 刷新下载任务状态
    refresh();

    // 回报所有安装的应用
    final ArrayList<CashbackTask> list = DBUtils.queryInstallation(mContext);
    if (list != null && list.size() != 0) {
      MarketAPI.reportInstallation(mContext, this, list);
      
      // 延迟10秒发送返利申请
      mHandler.postDelayed(new Runnable() {
        
        @Override
        public void run() {
          // 回报同步失败的任务
          for (CashbackTask task : list) {
            if (task.source == CashbackTask.SOURCE_REBATE) {
              MarketAPI.requestReward(mContext, CashbackManager.this, task.packageName);
            } else {
              // 标记安装任务已经提交完成
              task.status = RebateTask.STATUS_INVALID;
              DBUtils.insertOrUpdateTask(mContext, task);
            }
          }
        }
      }, 10000);
    }
  }
  
  /**
   * 读取账户余额
   */
  public void requestBalance() {
    MarketAPI.getExchangeBalance(mContext, this);
  }
  
  /**
   * 获取所有激活的返利任务
   */
  public HashMap<String, CashbackTask> getRebateTasks() {
    return mTasks;
  }
  
  /**
   * 获取账户余额
   */
  public int getBalance() {
    return mBalance;
  }
  
  /**
   * 更新任务状态
   */
  public synchronized void updateStatus(String pkgName, int status) {
    if (mTasks == null) {
      return;
    }

    CashbackTask t = mTasks.get(pkgName);
    if (t == null) {
      t = new CashbackTask();
      t.packageName = pkgName;
      t.status = status;
    } else {
      t.status = status;
    }

    requestBalance();
    DBUtils.insertOrUpdateTask(mContext, t);
  }

  /**
   * 刷新下载状态
   */
  private synchronized void refresh() {

    if (mCursor == null) {
      return;
    }

    mCursor.requery();

    while (mCursor.moveToNext()) {
      String pkgName = mCursor.getString(mCursor
          .getColumnIndex(DownloadManager.COLUMN_DESCRIPTION));
      CashbackTask task = mTasks.get(pkgName);

      if (task == null) {
        task = new CashbackTask();
        task.packageName = pkgName;
      }
      
      int status = translateStatus(mContext, pkgName,
          mCursor.getInt(mCursor.getColumnIndex(DownloadManager.COLUMN_STATUS)));
      if (status != -1 && task.status != RebateTask.STATUS_REBATED) {
        task.status = status;
      }
      task.taskId = mCursor.getLong(mCursor
          .getColumnIndex(DownloadManager.COLUMN_ID));
      mTasks.put(task.packageName, task);
    }

    setChanged();
    // 通知监听者状态更新
    notifyObservers(mTasks);
  }
  
  /**
   * 转换下载任务的状态值为返利任务可解析的状态值
   */
  private static int translateStatus(Context context, String pkgName,
      int status) {
    if (status == DownloadManager.STATUS_RUNNING
        || status == DownloadManager.STATUS_PENDING
        || status == DownloadManager.STATUS_PAUSED) {
      return RebateTask.STATUS_DOWNLOADING;
    } else if (status == DownloadManager.STATUS_FAILED) {
      return RebateTask.STATUS_NORMAL;
    } else if (status == DownloadManager.STATUS_SUCCESSFUL) {
      if (Session.get(context).getInstalledApps().contains(pkgName)) {
        return RebateTask.STATUS_REBATED;
      } else {
        return RebateTask.STATUS_DOWNLOADED;
      }
    } else {
      return -1;
    }
  }

  /**
   * 开始返利任务下载<br>
   * 
   * 插入下载任务并记录任务状态，并刷新观察者Cursor
   */
  public void startTask(String url, String pkgName, String title) {

    // 插入下载任务表
    long id = CashbackUtils.insertTask(mContext, url, title, pkgName);

    // 更新下载任务ID列表，重新观察数据库状态(重新绑定Cursor)
    int length;
    if (mTaskIdArray == null) {
      mTaskIdArray = new long[1];
      length = 1;
    } else {
      length = mTaskIdArray.length + 1;
      mTaskIdArray = Arrays.copyOf(mTaskIdArray, length);
    }
    mTaskIdArray[length - 1] = id;

    mCursor = CashbackUtils.queryWithId(mContext, mTaskIdArray);
    mCursor.registerContentObserver(mTaskObserver);

    // 插入返利任务表
    CashbackTask task = new CashbackTask();
    task.packageName = pkgName;
    task.taskId = id;
    task.status = RebateTask.STATUS_DOWNLOADING;
    task.source = CashbackTask.SOURCE_REBATE;
    DBUtils.insertOrUpdateTask(mContext, task);
  }

  /**
   * 兑换
   * @param id 兑换物品的ID
   */
  public void exchange(String id) {
    MarketAPI.exchange(mContext, this, id);
  }
  
  /**
   * 安装应用
   */
  public void install(String pkgName) {

    if (mTasks == null) {
      return;
    }
    CashbackTask task = mTasks.get(pkgName);

    if (task == null) {
      return;
    }
    CashbackUtils.install(mContext, task.taskId);
  }

  @Override
  public void onSuccess(int method, Object obj) {
    switch (method) {
      case MarketAPI.ACTION_GET_EXCHANGE_BALANCE:

        mBalance = Utils.getInt((String) obj);
        setChanged();
        notifyObservers();
        break;
        
      case MarketAPI.ACTION_EXCHANGE:
        
        int status = Utils.getInt((String) obj);
        switch (status) {
          case 0:
            // 物品已售罄
            Utils.makeEventToast(mContext,
                mContext.getString(R.string.exchange_error_1), false);
            break;
          case 1:
            // 兑换成功, 刷新账户余额
            Utils.makeEventToast(mContext,
                mContext.getString(R.string.exchange_success), false);
            requestBalance();
            setChanged();
            notifyObservers(true);
            break;
          case 2:
            // 兑换失败
            Utils.makeEventToast(mContext,
                mContext.getString(R.string.exchange_error_2), false);
            break;
        }
        break;
      case MarketAPI.ACTION_REQUEST_REWARD:
        
        @SuppressWarnings("unchecked")
        HashMap<String, Object> result = (HashMap<String, Object>) obj;
        String pkgName = (String) result.get(Constants.KEY_PACKAGE);
        updateStatus(pkgName, RebateTask.STATUS_REBATED);
        break;

    }
  }

  @Override
  public void onError(int method, int statusCode) {
    // TODO Auto-generated method stub

  }

  /**
   * 返利任务
   * 
   * @author andrew.wang
   * @date 2012-7-5
   * 
   */
  public static class CashbackTask {
    
    public static final int SOURCE_REBATE = 1;
    public static final int SOURCE_OTHERS = 0;
    
    /** 包名 */
    public String packageName;
    /** 下载任务ID */
    public long taskId;
    /** 返利任务状态 */
    public int status;
    /** 是否返利应用 */
    public int source;
  }

}
